{
 "metadata": {
  "language_info": {
   "codemirror_mode": {
    "name": "ipython",
    "version": 3
   },
   "file_extension": ".py",
   "mimetype": "text/x-python",
   "name": "python",
   "nbconvert_exporter": "python",
   "pygments_lexer": "ipython3",
   "version": "3.7.5-final"
  },
  "orig_nbformat": 2,
  "kernelspec": {
   "name": "python37564bit166e976e2fef40668cb4b6fa95113b74",
   "display_name": "Python 3.7.5 64-bit"
  }
 },
 "nbformat": 4,
 "nbformat_minor": 2,
 "cells": [
  {
   "source": [
    "# QAOA算法"
   ],
   "cell_type": "markdown",
   "metadata": {}
  },
  {
   "cell_type": "code",
   "execution_count": 2,
   "metadata": {
    "tags": []
   },
   "outputs": [
    {
     "output_type": "stream",
     "name": "stdout",
     "text": "Import Successfully!\n"
    }
   ],
   "source": [
    "from mindquantum.core import Circuit, Hamiltonian, UN, H, ZZ, RX, QubitOperator\n",
    "from mindquantum.framework import MQAnsatzOnlyLayer\n",
    "from mindquantum.simulator import Simulator\n",
    "import networkx as nx\n",
    "import mindspore.nn as nn\n",
    "import mindspore as ms\n",
    "import numpy as np\n",
    "from tqdm import trange\n",
    "import matplotlib as plt\n",
    "import src.full_qaoa as qaoa\n",
    "\n",
    "print('Import Successfully!')"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 3,
   "metadata": {},
   "outputs": [
    {
     "output_type": "display_data",
     "data": {
      "text/plain": "<Figure size 432x288 with 1 Axes>",
      "image/svg+xml": "<?xml version=\"1.0\" encoding=\"utf-8\" standalone=\"no\"?>\n<!DOCTYPE svg PUBLIC \"-//W3C//DTD SVG 1.1//EN\"\n  \"http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd\">\n<svg xmlns:xlink=\"http://www.w3.org/1999/xlink\" width=\"446.4pt\" height=\"302.4pt\" viewBox=\"0 0 446.4 302.4\" xmlns=\"http://www.w3.org/2000/svg\" version=\"1.1\">\n <metadata>\n  <rdf:RDF xmlns:dc=\"http://purl.org/dc/elements/1.1/\" xmlns:cc=\"http://creativecommons.org/ns#\" xmlns:rdf=\"http://www.w3.org/1999/02/22-rdf-syntax-ns#\">\n   <cc:Work>\n    <dc:type rdf:resource=\"http://purl.org/dc/dcmitype/StillImage\"/>\n    <dc:date>2022-01-20T04:21:11.482386</dc:date>\n    <dc:format>image/svg+xml</dc:format>\n    <dc:creator>\n     <cc:Agent>\n      <dc:title>Matplotlib v3.5.0, https://matplotlib.org/</dc:title>\n     </cc:Agent>\n    </dc:creator>\n   </cc:Work>\n  </rdf:RDF>\n </metadata>\n <defs>\n  <style type=\"text/css\">*{stroke-linejoin: round; stroke-linecap: butt}</style>\n </defs>\n <g id=\"figure_1\">\n  <g id=\"patch_1\">\n   <path d=\"M 0 302.4 \nL 446.4 302.4 \nL 446.4 0 \nL 0 0 \nz\n\" style=\"fill: #ffffff\"/>\n  </g>\n  <g id=\"axes_1\">\n   <g id=\"LineCollection_1\">\n    <path d=\"M 327.314327 270.208264 \nL 401.712397 126.860988 \n\" clip-path=\"url(#pf17c30f476)\" style=\"fill: none; stroke: #000000\"/>\n    <path d=\"M 327.314327 270.208264 \nL 227.260527 32.191736 \n\" clip-path=\"url(#pf17c30f476)\" style=\"fill: none; stroke: #000000\"/>\n    <path d=\"M 327.314327 270.208264 \nL 44.687603 118.283142 \n\" clip-path=\"url(#pf17c30f476)\" style=\"fill: none; stroke: #000000\"/>\n    <path d=\"M 327.314327 270.208264 \nL 106.293438 265.434249 \n\" clip-path=\"url(#pf17c30f476)\" style=\"fill: none; stroke: #000000\"/>\n    <path d=\"M 401.712397 126.860988 \nL 227.260527 32.191736 \n\" clip-path=\"url(#pf17c30f476)\" style=\"fill: none; stroke: #000000\"/>\n    <path d=\"M 401.712397 126.860988 \nL 106.293438 265.434249 \n\" clip-path=\"url(#pf17c30f476)\" style=\"fill: none; stroke: #000000\"/>\n    <path d=\"M 401.712397 126.860988 \nL 44.687603 118.283142 \n\" clip-path=\"url(#pf17c30f476)\" style=\"fill: none; stroke: #000000\"/>\n    <path d=\"M 227.260527 32.191736 \nL 106.293438 265.434249 \n\" clip-path=\"url(#pf17c30f476)\" style=\"fill: none; stroke: #000000\"/>\n    <path d=\"M 227.260527 32.191736 \nL 44.687603 118.283142 \n\" clip-path=\"url(#pf17c30f476)\" style=\"fill: none; stroke: #000000\"/>\n    <path d=\"M 106.293438 265.434249 \nL 44.687603 118.283142 \n\" clip-path=\"url(#pf17c30f476)\" style=\"fill: none; stroke: #000000\"/>\n   </g>\n   <g id=\"PathCollection_1\">\n    <defs>\n     <path id=\"m1e692b7793\" d=\"M 0 8.660254 \nC 2.296726 8.660254 4.499694 7.747755 6.123724 6.123724 \nC 7.747755 4.499694 8.660254 2.296726 8.660254 0 \nC 8.660254 -2.296726 7.747755 -4.499694 6.123724 -6.123724 \nC 4.499694 -7.747755 2.296726 -8.660254 0 -8.660254 \nC -2.296726 -8.660254 -4.499694 -7.747755 -6.123724 -6.123724 \nC -7.747755 -4.499694 -8.660254 -2.296726 -8.660254 0 \nC -8.660254 2.296726 -7.747755 4.499694 -6.123724 6.123724 \nC -4.499694 7.747755 -2.296726 8.660254 0 8.660254 \nz\n\" style=\"stroke: #1f78b4\"/>\n    </defs>\n    <g clip-path=\"url(#pf17c30f476)\">\n     <use xlink:href=\"#m1e692b7793\" x=\"327.314327\" y=\"270.208264\" style=\"fill: #1f78b4; stroke: #1f78b4\"/>\n     <use xlink:href=\"#m1e692b7793\" x=\"401.712397\" y=\"126.860988\" style=\"fill: #1f78b4; stroke: #1f78b4\"/>\n     <use xlink:href=\"#m1e692b7793\" x=\"227.260527\" y=\"32.191736\" style=\"fill: #1f78b4; stroke: #1f78b4\"/>\n     <use xlink:href=\"#m1e692b7793\" x=\"106.293438\" y=\"265.434249\" style=\"fill: #1f78b4; stroke: #1f78b4\"/>\n     <use xlink:href=\"#m1e692b7793\" x=\"44.687603\" y=\"118.283142\" style=\"fill: #1f78b4; stroke: #1f78b4\"/>\n    </g>\n   </g>\n  </g>\n </g>\n <defs>\n  <clipPath id=\"pf17c30f476\">\n   <rect x=\"7.2\" y=\"7.2\" width=\"432\" height=\"288\"/>\n  </clipPath>\n </defs>\n</svg>\n",
      "image/png": "iVBORw0KGgoAAAANSUhEUgAAAb4AAAEuCAYAAADx63eqAAAAOXRFWHRTb2Z0d2FyZQBNYXRwbG90bGliIHZlcnNpb24zLjUuMCwgaHR0cHM6Ly9tYXRwbG90bGliLm9yZy8/fFQqAAAACXBIWXMAAAsTAAALEwEAmpwYAABd4ElEQVR4nO3ddVzUyf8H8NfSGByIgIBBNwqintgKtp6NcXbggXkGISWCEnaAgajYhYmtiHgqehYI0iK2AgbS7O78/rjv+bvwlNjd2Zjn43EP7yG7My+Q3ffOfGbmwyGEEDAMwzCMjJCjHYBhGIZhRIkVPoZhGEamsMLHMAzDyBRW+BiGYRiZwgofwzAMI1NY4WMYhmFkCit8DMMwjExhhY9hGIaRKazwMQzDMDKFFT6GYRhGprDCxzAMw8gUVvgYhmEYmcIKH8MwDCNTWOFjGIZhZAorfAzDMIxMYYWPYRiGkSms8DEMwzAyhRU+hmEYRqawwscwDMPIFFb4GIZhGJnCCh/DMAwjU1jhYxiGYWSKAu0ADCPLCksqcfTeC2S8KUZxBRdqKgqwaKaGUQ7NodlImXY8hpFKHEIIoR2CYWRN8vOPiEjIwbWsAgBAJZf/5WsqCnIgAHqYa8G9uwnatFCnE5JhpBQrfAwjYnuTnmL52QxUcHn41quPwwFUFOThM8AC4zsaiCwfw0g7NtXJMCL0R9FLR3k1/7uPJQQor+Zh+dl0AGDFj2EEhC1uYRgRSX7+EcvPZtSo6P1VeTUfy89mIOXFR+EEYxgZwwofw4hIREIOKri8Oj23gstDZEKOgBMxjGxihY9hRKCwpBLXsgq+eU3vWwgBrmYWoKikUrDBGEYGscLHMCJw9N6LerfBAXD0fv3bYRhZxwofw4hAxpviv21ZqIsKLh8Zrz8LKBHDyC5W+BhGBIoruAJqp1og7TCMLGOFj2FEQE1FMDuH1FQUBdIOw8gyVvgYRgQsmqlBSZ5TrzZUFORgodtYQIkYRnaxwscwQpaWloarO0JQWVm/FZlcHg8j7PUFlIphZBcrfAwjJElJSRgyZAicnJxgZ2EMJ8tm4NRx0McBQF6lYmh/Z9y8eVOgORlG1rDCxzACRAjBhQsX0LNnT4wdOxZ9+/ZFXl4evL29Ma+3JVQU5OvUroqiPI4uc8X06dMxZswYDB8+HBkZGQJOzzCygRU+hhEAHo+HI0eOoF27dli4cCGmTZuGrKwsuLu7Q1VVFQDQpoU6fAZYQFWxdi87VUU5+AywgH3LJpg8eTIyMzPRsWNHdO3aFTNnzsTr16+F8S0xjNRihY9h6qGyshLbt2+HpaUl1q5di6VLlyIlJQXjx4+HouK/V2CO72gAnwGWUJQjAP/b+/o4AFQV5eEzwPJvB1SrqqrCw8MDmZmZUFNTg42NDfz8/FBcXCzg745hpBMrfAxTByUlJVizZg2MjY0RGxuLqKgo3LhxA4MHD4ac3LdfVuM6tITS9Ui0bgooK8hBReHvj1dRkIMc4cFA8RMOuXb8z7syNGnSBCtXrsT9+/fx7NkzmJmZYePGjaiqqhLUt8kwUondj49haqGwsBAbN25EZGQkevXqBS8vL9jb29eqjUOHDmHNmjVISkrC+9IqHL3/AhmvP6O4ohpqKoqw0G0ME/kiTPvZBbm5uZCXr9l1weTkZHh5eSE7OxvLly/HqFGjvluEGUYWscLHMDXw/PlzrF69Grt378bIkSOxePFimJqa1rodLpcLa2trbNq0Cb179/7mYzt27IglS5bgp59+qlUf8fHx8PDwAIfDQXh4OHr27FnrnAwjzdjHQYb5hoyMDEydOhV2dnZQVFREamoqtm3bVqeiBwB79uyBrq4unJ2dv/vYWbNmYdOmTbXuo1evXrhz5w4WLlyI6dOnY8CAAUhJSalLXIaRSqzwMcxX3L17FyNGjEC3bt1gaGiI7OxsrFy5Enp6enVus7KyEoGBgQgODganBhv6Ro0aheTkZGRmZta6Lzk5OYwZMwbp6eno168fevfujcmTJ+PZs2d1ic4wUoUVPob5H0IIrly5AmdnZwwfPhzdunVDXl4e/Pz80KRJk3q3Hx0dDUtLS3Tp0qVGj1dRUcH06dMRGRlZ5z6VlJQwd+5cZGdno3nz5rC3t8fixYvx4cOHOrfJMJKOXeNjZB6fz8fJkycREhKCz58/w9PTE+PGjYOSkpLA+igrK4OpqSlOnToFBweHGj/v2bNnsLe3R35+Pho1alTvHK9evUJgYCCOHTsGDw8PzJkzByoqKvVul2EkCRvxMTKruroau3btgrW1NUJCQuDt7Y20tDRMnjxZoEUPACIjI9GxY8daFT0AaNmyJbp37469e/cKJIeenh62bt2K69ev4+bNmzA3N0dMTAx4PJ5A2mcYScBGfIzMKS0tRXR0NFavXg0zMzN4eXmhV69eNbruVhfFxcUwNTVFfHw8rK2ta/38+Ph4zJ07F48ePRJ4xhs3bsDDwwOfP39GWFgY+vXrJ7SfA8OICzbiY2TGhw8fEBQUBCMjI1y7dg1Hjx7FpUuX4OTkJNQ3+/Xr16N37951KnoA0LNnT/D5fCQmJgo4GdC5c2f89ttvWLZsGX799Vc4OTnh7t27Au+HYcQJK3yM1Hv16hUWL14MExMT5OXl4dq1a4iNjUX79u2F3vf79++xfv16LF26tM5tcDicOm9tqGn7Q4cORWpqKsaMGYMhQ4ZgzJgxyM3NFUp/DEMbK3yM1MrJyYGrqytsbGxQXV2Nhw8fYseOHbCwsBBZhpUrV2L48OEwMTGpVzsTJkzAlStX8PLlSwEl+zcFBQW4uroiKysLNjY2+PHHHzF37lwUFBQIrU+GoYEVPkbqPHjwAKNHj4ajoyN0dXWRlZWFdevWoUWLFiLN8ebNG2zbtg1+fn71bktNTQ3jxo3D1q1bBZDs2xo2bAhfX1+kp6cDACwtLREUFITS0lKh980wosAWtzBSgRCCxMREhIaGIiUlBQsWLICrqysaN25MLdO8efPA4XCwbt06gbSXnp6OXr16IT8/X+CrTr8lNzcXPj4+SExMREBAAKZNmwYFBQWR9c8wgsYKHyPR+Hw+zpw5g5CQEBQUFMDT0xMTJkyAsrIy1VzPnz+HnZ0dHj9+DB0dHYG16+TkhOnTp2Ps2LECa7Om7t69Cw8PD7x69QohISEYOnQoWwHKSCRW+BiJxOVycfDgQYSFhUFRURFeXl4YMWJEje9kIGyurq7Q1NRESEiIQNs9fvw4Vq1ahRs3bgi03ZoihOD8+fPw9PRE48aNER4ejs6dO1PJwjB1xQofI1HKy8uxc+dOrFy5Eq1atYK3tzf69OkjViOPnJwcdOzYEVlZWQI56uyvuFwujIyMcPLkyVrfDkmQeDwe9u3bBz8/P9jb2yMkJASWlpbU8jBMbbDFLYxE+PTpE0JCQmBoaIgLFy5g//79SEhIQN++fcWq6AHA0qVLMW/ePIEXPeCPlZe//PILIiIiBN52bcjLy2PixInIzMxEly5d0L17d7i6uuLVq1dUczFMTbDCx4i1t2/fwsvLC0ZGRkhPT8fly5dx8uRJODo60o72VWlpabh06RLmzZsntD6mT5+O2NhYvH//Xmh91JSKigoWLVqEzMxMqKurw9bWFr6+viguLqYdjWH+Eyt8jFjKy8uDu7s7LC0tUVJSgnv37mH37t2wsbGhHe2b/P39sXjxYqipqQmtD21tbQwaNAg7d+4UWh+1paGhgfDwcDx48AAvXryAqakpNmzYgKqqKtrRGOZfWOFjxMqjR48wfvx4tG/fHurq6khPT8emTZtgYGBAO9p33bt3D0lJSZg1a5bQ+5o9ezYiIyPF7nDpli1bYteuXbh06RLOnz8PCwsLHDx4EHw+n3Y0hvmCFT5GLNy8eRODBw9Gnz59YGtri9zcXKxYsUKgWwGEzdfXFz4+PlBVVRV6Xx06dICGhgbOnz8v9L7qonXr1jh79iyio6OxZs0adOjQAVeuXKEdi2EAsFWdDEV/Lo0PCQnBixcvsHjxYkyePFkkhUPQfvvtN4wfPx5ZWVki21y+a9cuHD58GGfPnhVJf3VFCMGRI0ewZMkSmJiYICwsDG3atKEdi5FhrPAxIsfj8XDkyBGEhoaCz+fDy8sLLi4uEnsaCCEEPXr0wOTJkzFlyhSR9VteXo5WrVrh5s2b9T4LVBSqqqqwbds2BAcHo0+fPggKCkKrVq1ox2JkEJvqZESmoqIC27Ztg7m5OTZt2oTly5cjOTkZ48aNk9iiBwCXL1/G27dvMWHCBJH2q6qqiilTpmDz5s0i7beulJSUMHv2bGRlZcHAwABt27bFokWLxGJ1KiNbWOFjhO7z589YuXLll43XO3fuxG+//YaBAweK3R682iKEwMfHB4GBgVSKt5ubG2JiYiTqAGk1NTUsW7YMqampKCkpgbm5OcLDw1FeXk47GiMjWOFjhKagoAB+fn4wNDTE/fv3ce7cOZw5cwZdu3alHU1gTp06hcrKSowaNYpK/wYGBujUqRP2799Ppf/60NXVxZYtW3D9+nUkJSXB3Nwcu3btEruVqoz0YYWPEbhnz55h7ty5MDc3x7t375CUlIQDBw5I3YIGPp8PPz8/BAUFQU6O3ktp9uzZiIiIgKRerrewsMCxY8dw8OBBbN++HXZ2djh79qzEfj+M+GOFjxGYx48fY9KkSbC3t4eKigrS0tKwdetWiVh4UReHDx+GqqoqBg8eTDWHs7MzysvLqR1cLSidOnXC9evXERwcjIULF6JXr174/fffacdipBArfEy93blzB8OGDUPPnj1hZmaGnJwchIeHQ1dXl3Y0oeFyuQgICMDy5cupX6eUk5ODu7s79fM7BYHD4WDIkCF49OgRfv75ZwwdOhQuLi7IycmhHY2RIqzwMXVCCMGlS5fg5OSEUaNGoVevXsjLy4OPjw80NDRoxxO63bt3Q09PD05OTrSjAAAmTZqE8+fP4/Xr17SjCISCggKmT5+OrKwstGnTBh07dsTs2bPx7t072tEYKcAKH1MrPB4PsbGxaN++PebNm4dJkyYhJycHc+bMQYMGDWjHE4nKykosW7YMwcHB1Ed7f1JXV8eYMWOwbds22lEEqmHDhvDx8UFGRgYUFBRgZWWFZcuWoaSkhHY0RoKxDexMjVRVVWHv3r0IDw/HDz/8AG9vb/z0009UF3XQEhERgTNnzojdiSmpqano27cvnj59CkVFRdpxhOLJkyfw9fVFQkIC/P39MW3aNKn9XhnhYYWP+aaSkhJERUVhzZo1sLS0hLe3N3r06CE2Ix1RKysrg6mpKU6fPo22bdvSjvMvPXr0gLu7O1xcXGhHEap79+7B09MTz58/R0hICIYNGyazv5NM7cnex3WmRoqKihAYGAgjIyPcvHkTJ06cwMWLF9GzZ0+ZfoOJiIiAo6OjWBY9AJg1a5ZULHL5HgcHB1y6dAkbNmzAsmXLvqwIZZiaYCM+5m9evHiBNWvWYNeuXRg2bBg8PDxgbm5OO5ZYKC4uhomJCa5evQpra2vacb6quroaBgYGOHfuHFq3bk07jkjw+Xzs27cPfn5+aN26NUJDQ2FlZUU7FiPG2IiPAQBkZWVh+vTpX94sU1JSEB0dzYreX6xbtw59+/YV26IHAIqKivjll19kYtT3Jzk5OUyYMAEZGRno3r07evTogRkzZuDly5e0ozFiio34ZNy9e/cQGhqKhIQEzJo1C3PmzIGmpibtWGLn/fv3MDMzw+3bt2FsbEw7zje9efMGlpaWyMvLg7q6Ou04IvfhwweEhoZi+/btmDlzJjw9PfHDDz/QjsWIETbik0GEEFy9ehV9+vTBkCFD0KlTJ+Tl5WHp0qWs6P2H8PBwjBgxQuyLHgA0a9YM/fv3x65du2hHoUJDQwNhYWF4+PAh3rx5AzMzM6xbtw6VlZW0ozFigo34ZAifz8epU6cQGhqKDx8+wNPTEz///DOUlZVpRxNrb968gZWVFZKTk9GiRQvacWrkxo0bmDJlCjIyMmRyy8lfpaamwsvLC48fP0ZwcDDGjBkj8z8TWccKnwyorq7GgQMHEBYWBhUVFXh7e2PYsGGQl5enHU0izJs3DxwOB+vWraMdpcYIIWjbti1CQ0PRt29f2nHEwrVr17B48WLweDyEhYXB2dmZdiSGElb4pFhZWRl27NiBVatWwcjICN7e3nB2dpbp7Qi19ezZM9jb2+Px48fQ0dGhHadWoqOjceLECZw+fZp2FLFBCMHRo0exZMkSGBkZISwsDHZ2drRjMSLGCp8U+vjxIyIiIrBx40Y4OjrCy8sLP/74I+1YEmnGjBnQ0tLCihUraEeptbKyMrRs2RK///47DA0NaccRK9XV1di2bRuCgoLQu3dvBAUFwcDAgHYsRkTYRLcUef36NTw8PGBsbIysrCzEx8fj+PHjrOjVUXZ2No4fP47FixfTjlInDRo0wOTJk7F582baUcSOoqIiZs2ahezsbBgZGcHBwQELFy5EUVER7WiMCLDCJwVyc3Pxyy+/wNraGhUVFbh//z5iYmLYJt56CgwMxLx58yT6bhNubm7YuXMnysvLaUcRS40bN0ZgYCDS0tJQVlYGc3NzhIaGsp+XlGOFT4IlJydj7Nix+PHHH9G0aVNkZGRgw4YNaNWqFe1oEi81NRWXLl3C/PnzaUepF2NjY3To0AEHDx6kHUWsNWvWDJs3b8aNGzdw9+5dmJmZYceOHeDxeLSjMULACp8Eun79OgYOHIj+/fujbdu2ePLkCYKDg6GtrU07mtTw9/eHh4cHGjduTDtKvc2ePRubNm0Cu5z/febm5jh69CiOHDmCXbt2oU2bNoiLi2M/OynDFrdICEIIzp49i5CQkC/X8iZNmgQVFRXa0aTO3bt3MWTIEOTk5EBVVZV2nHrj8/kwMzPD3r170bFjR9pxJAYhBHFxcfDy8kLTpk0RHh7OrpdLCVb4xByXy8Xhw4cRGhoKOTk5eHl5YeTIkVBQUKAdTWr169cPP/30E9zd3WlHEZg1a9bg/v372Lt3L+0oEofL5SImJgYBAQFwdHTEihUrYGpqSjsWUw+s8ImpiooK7Ny5EytXrkTz5s3h7e2Nfv36sT14Qnb9+nVMnDgRmZmZUFJSoh1HYD58+AAjIyNkZGRI3H5EcVFWVob169dj9erVGD16NPz9/dnPUkKxa3xipri4GGFhYTA0NMTZs2exZ88eJCYmon///qzoCRkhBL6+vggICJCqogf8cX7lyJEjsX37dtpRJFaDBg3g7e2NjIwMKCkpwcrKCoGBgSgpKaEdjaklVvjExLt377BkyRIYGhoiJSUFFy5cwOnTp9G5c2fa0WTGpUuX8PbtW4wfP552FKGYNWsWtmzZAi6XSzuKRGvatCnWrl2Lu3fvIisrC6ampoiMjER1dTXtaEwNscJH2dOnTzF79mxYWFjgw4cP+P3337Fv3z6ZuYmouCCEwMfHB4GBgVJ7/dTOzg6tWrXCqVOnaEeRCoaGhti3bx/OnDmD48ePw9raGkePHmUrQCUAK3yUpKWlYcKECXBwcECjRo3w+PFjbN68GUZGRrSjyaRTp06huroao0aNoh1FqP7c2sAITtu2bXHp0iVERERg+fLlcHR0RGJiIu1YzDewwidiSUlJGDJkCJycnGBlZYXc3FyEhoaiWbNmtKPJLD6fDz8/PwQFBUn97WqGDx+OjIwMpKWl0Y4idXr37o179+5hzpw5mDRpEgYPHsx+zmJKul/lYoIQggsXLqBHjx4YM2YM+vTpg7y8PHh7e8vkHbLFzaFDh9CgQQMMGjSIdhShU1JSwowZMxAZGUk7ilSSk5PDzz//jIyMDPTq1Qs9e/bEtGnT8OLFC9rRmL9g2xmEiMfjITY2FqGhoaiqqoKXlxdGjx4NRUVF2tGY/+FyubCyssLmzZvh5OREO45IvHr1CjY2Nnj69CnU1NRox5FqHz9+RFhYGLZt2wZXV1d4enqyD7tigI34hKCyshLbt2+HpaUl1q5di6VLlyIlJQXjx49nRU/MxMTEQF9fH7169aIdRWT09PTg7OyM3bt3044i9dTV1RESEoLk5GS8e/cO5ubmWLt2LSorK2lHk2lsxCdAnz9/xrZt27BmzRrY2trC29sb3bp1Y/vvxFRlZSXMzMxw4MABdOrUiXYckUpMTISrqyvS09PZ76cIpaWlwcvLC6mpqQgODsbYsWOl/rqyOGI/cQEoLCyEv78/jIyMcPv2bZw+fRrnz59H9+7d2ZuKGIuKioKNjY3MFT0A6Nq1K5SUlHDlyhXaUWSKtbU1Tp8+jZiYGGzcuBEODg64ePEi7Vgyh4346uH58+dYvXo1du/ejREjRsDDw4Od4SchysrKYGJigri4OLRt25Z2HCq2bt2K8+fP4/jx47SjyCRCCI4dOwZvb2+0atUK4eHhsLe3px1LJrARXx1kZGRgypQpaNOmDRQUFPDo0SNERUWxoidBNm3ahE6dOsls0QOAn3/+GYmJicjPz6cdRSZxOByMGDECaWlpGD58OAYMGICff/4ZeXl5tKNJPVb4auHu3bsYMWIEunXrBkNDQ+Tk5GDVqlXQ19enHY2pheLiYqxatQrLli2jHYWqRo0aYcKECdiyZQvtKDJNUVERbm5uyMrKgpmZGdq1a4dff/0VhYWFtKNJLVb4voMQgitXrsDZ2RnDhw9Ht27dkJeXB39/fzRp0oR2PKYO1q5di379+sHKyop2FOrc3d0RHR2NiooK2lFkXuPGjREQEIDHjx+jqqoKFhYWCAkJQVlZGe1oUodd4/sPfD4fJ0+eREhICD5//gxPT0+MGzdO6k7tlzVFRUUwNzfH7du3YWxsTDuOWOjXrx/GjRuHiRMn0o7C/EV2djaWLFmCW7duITAwEJMmTZLac2RFjRW+f6iqqsL+/fsRFhaGRo0awdvbG0OHDmVLjqWEp6cnPn78iK1bt9KOIjZOnz6N4OBg3L59m3YU5itu374NDw8PFBYWIjQ0FIMGDWKrxeuJFb7/KS0txfbt27F69WqYmZnB29sbvXr1Yr9gUuTNmzewsrJCSkoKmjdvTjuO2ODxeDAxMcGhQ4fQoUMH2nGYryCE4MyZM/Dy8kKTJk0QHh6Ojh070o4lsWR+GPP+/XsEBQXB0NAQ165dQ2xsLC5fvgwnJydW9KTMihUrMGnSJFb0/kFeXh5ubm6IiIigHYX5DxwOB4MGDUJycjImT56MUaNGYcSIEcjKyqIdTSLJ7Ijv1atXWLNmDXbs2IEhQ4bAw8MDlpaWtGMxQvLs2TPY29sjPT0d2tratOOInaKiIpiYmCArKwtaWlq04zDfUV5ejg0bNmDVqlUYOXIkAgIC2B1eakFiRnyFJZXYci0X8w89wNSY3zH/0ANsuZaLopLanXmXnZ2NGTNmwNraGtXV1Xj48CF27tzJip6UW7ZsGWbOnMmK3n/Q1NTEsGHDEB0dTTsKUwOqqqrw9PRERkYGGjRoAGtrawQEBODz58+0o0kEsR/xJT//iIiEHFzLKgAAVHL5X76moiAHAqCHuRbcu5ugTQv1/2znwYMHCA0NxZUrV+Du7o65c+eiadOmQk7PiIPs7Gw4OjoiOzsbGhoatOOIrXv37mH48OF48uQJ5OXlacdhauHp06fw8/PD5cuX4evrC1dXV3Yg/jeI9Yhvb9JTjIlKwqX0t6jk8v9W9ACg4n9/d/HxW4yJSsLepKd/+zohBNeuXUO/fv0waNAgdOjQAXl5eVi2bBkrejJk6dKlmD9/Pit63+Hg4AA9PT3ExcXRjsLUkoGBAfbs2YNz587h1KlTsLKywpEjRyDm4xpqxHbEtzfpKZafTUd5Nf/7D/4fVUU5+AywxLgOLREXF4fQ0FAUFBTAw8MDEydOhLKyshATM+IoNTUVzs7OyM7ORuPGjWnHEXt79+5FTEwMLl26RDsKUw+XL1+Gh4cHFBUVER4eju7du9OOJFbEsvAlP/+IMVFJKK/m1fq5ihwChWsboVL2Dt7e3hgxYgSbtpFhw4YNQ9euXbFgwQLaUSRCZWUlWrZsiWvXrsHCwoJ2HKYe+Hw+Dh48CB8fH1hbWyMkJAS2tra0Y4kFsZzqjEjIQQW39kUPAKr5BObD5+L+/ftwcXFhRU+G/f777/j999/h5uZGO4rEUFZWxowZMxAZGUk7ClNPcnJyGDduHDIyMuDs7AxnZ2dMmTIFz58/px2NOrErfIUllbiWVYA6j0M5ckj/KIf3pVUCzcVIHj8/P/j4+EBVVZV2FIkyc+ZM7N27l60QlBLKysqYP38+srKyoKenBzs7uy8nGMkqsSt8R++9qHcbHABH79e/HUZyXb9+HVlZWZg2bRrtKBKnRYsW6NmzJ/bu3Us7CiNAP/zwA5YvX46UlBS8f/8eZmZmWL16tUweUC521/jmH3qAEw9f1bsd28blGN2yAkpKSn/7T1lZ+V9/97W/V1RUZCe3SChCCLp3745p06Zh0qRJtONIpKtXr2L27NlITU1lrwMp9fjxY3h7eyM5ORlBQUH4+eefa3UmcWFJJY7ee4GMN8UoruBCTUUBFs3UMMqhOTQbifdCQrErfFNjfkd8xrt6t6NZ8QqWBddQVVWFqqoqVFZWfvn/v/73X39fXV0NRUXFWhXL+n6tLs+Rl5dnb0z/cOHCBcybNw+pqansNPs6IoTAxsYGERER6NGjB+04jBBdv34dHh4eKC8vR1hYGPr06fPN9xRB7a2mSewKn6BGfMPs9LF2tF2dn08I+WpBrGshFfRz/vwaIUSsC7OysjIUFRVFdncLQgg6dOiAxYsXw8XFRSR9SqvIyEjEx8fj6NGjtKMwQkYIwfHjx+Ht7Y0WLVogLCwMDg4O/3rcH9vMMlDB5X1zHQaHA6goyMNngAXGdzQQXvA6EruPwxbN1KCs8OZfm9VrQ0VBDha69duzxeFwoKysLPZ7/3g8nkALaVVVFSoqKlBcXCyw9qqqqqCgoCCS4puSkoKCggIoKiri3LlztWpPQUGBjZ7/YsKECfD19cWLFy/Ywd5SjsPhYPjw4Rg8eDCio6MxePBg9OjRA8HBwTAyMgJQu73VhADl1TwsP5sOAGJX/MRuxFdYUonOYfH1KnxK8hzc8nIS+3lmWUEIAZfLFfqouKKiAidPnoS1tTWaNm1a6/a4XC61UXFtniPKLTpz5syBuro6goKCRNYnQ19JSQnWrFmD9evXY/z48Rg2fT7cjmTWaW+1qqI8Drl2ROvm6oIPWkdiV/gAwHXPXVxKf1u3LQ2ED17+A3h3bYoZM2aw8+pkyP79+7FhwwbcunWrTiM3Pp+P6upqkU1X1/U5HA5H4MX3v75WUFCAZcuWISYmBg0bNqxVe2z0LPnevXuHoKAgHC9oCgVDB/yxZr52OBygr5UOtoxvJ/iAdSSWha8+J7eoKspjaVd1RK/0R15eHoKDgzFq1Ch2B3UpV11dDSsrK2zZsgVOTk604wjVX0fPgpzi/q+/v3r1KvT19b+MomvynL8uDqN1fbkm7bHFYd9XWFIJx9ArqObVvVQoK8jhpmcvsZmFE8vCB9TvrM4/55MvX74MLy8vAEBYWJjUvyHKsujoaOzbtw/x8fG0o0idEydOIDw8HDdv3qzxcwghqK6upjIqrk17fD6fevGtyddofnDfci0Xay9n1Xvdxa+9zTCzm7EAk9Wd2BY+QDAriPh8Po4cOQIfHx8YGRkhNDQUbdu2FW5wRqQqKythZmaGgwcPwtHRkXYcqcPlcmFkZIQTJ05I3WuHx+N9KdC0iu/3vlZZWQl5eXlqhTn6MRc3X3Hr/bOu70p7QRLrwgcAKS8+IjIhB1czC8DBH7ci+pOi3B9TXH1bN8esHibfvHhaVVWF7du3Iygo6MtqJWNj8fj0wdTPxo0bceHCBXY7HSEKCQlBTk4Ou1EtBYQQ8Hg8aoX5pfFgVGia1vv7cLLQRvSk9gL4idSf2Be+PxWVVOLo/RfIeP0ZxRXVUFNRhHmzxtj46zhsWh2Knj171qidv65WGjduHHx9faGjoyPk9IywlJaWwsTEBGfPnoW9vT3tOFKroKAAZmZmyMnJgaamJu04jAiJy95qQZKYFR+ajZQxs5sx1o62Q/Sk9lg72g6/dDfGrOmTEBERUeN2GjVqBH9/f6Snp0NOTg5WVlZYunQpO5BXQkVERKBLly6s6AmZlpYWBg8ejJ07d9KOwojYH3ur61cqBLG3WpAkpvD9lwkTJiA+Ph4vXtTuUGptbW2sX78ed+/eRU5ODkxNTbFx40ZUVbG7OkiKT58+YdWqVVi2bBntKDJh9uzZiIyMBI9Xt1uGMZKHEILmVc/r/b5IAIxsKz6HIEh84WvcuDHGjRuHrVu31un5hoaG2Lt3L86fP4+zZ8/C0tIS+/fvB59f9xVMjGisXbsW/fv3h6WlJe0oMqFDhw7Q1NTEuXPnaEdhhIzP5+PUqVPo3LkzfnWfAbNG1XXYwfcHDgfoaa4lNlsZAAm6xvct6enp6NWrF/Lz86GkpFSvtq5evQpPT09UV1cjNDT0uwe2MnQUFRXBzMwMv//++5cjlRjhi4mJwcGDB1nxk1LV1dU4cOAAwsLCoKysDG9vbwwfPhyprz7Xa281O7lFSJycnDB9+nSMHTu23m0RQhAbGwsfHx80b94coaGhaN9ePFYjMX/w8PBAcXExtmzZQjuKTKmoqEDLli1x48YNmJrWf6UfIx7Kysqwfft2rF69GiYmJvDy8oKzs/PfPvQLYm+1uJD4qc4/zZo1q1aLXL6Fw+Fg5MiRSE1NhYuLC4YMGQIXFxdkZ2cLpH2mfl6/fo3t27fD19eXdhSZo6KigqlTp2Lz5s20ozAC8P79ewQFBcHQ0BDXrl3DkSNHcOXKFfTu3ftfM13jOxrAZ4Al5MEDyLeLH4fzx0hPHIseIEWF76effkJ+fj4ePnwosDYVFRUxc+ZMZGdnw87ODo6OjnB3d8ebN28E1gdTeytWrMDkyZPZHQMo+eWXXxATE4PS0lLaUZg6evHiBRYuXAgTExPk5eUhISEBsbGx6NChwzef19e4IYqPLUNXwx+grCAHlX+s9lRRkIOyghz6WungkGtHsSx6gBRNdQJAcHAw8vPzERUVJZT2CwsLsWLFCsTExMDd3R2LFy+GmpqaUPpivi4/Px9t27ZFeno6tLW1aceRWUOGDMHAgQPh6upKOwpTCxkZGVi5ciWOHz+OyZMn49dff0WLFi1q/PxFixahrKwMkZGRX91bbaHbGCPbiv8d2EGkyJs3b4i6ujp5//69UPt5+vQpmThxItHW1iZr164lFRUVQu2P+X9Tp04lS5YsoR1D5l28eJG0bt2a8Pl82lGYGrhz5w4ZPnw40dLSIoGBgaSwsLDWbbx8+ZJoaGiQly9fCiGhaEnNVCcA6OjoYMCAAdi1a5dQ+2nVqhViYmJw+fJlXL58GRYWFtizZw/b3yRkWVlZOHXqFBYtWkQ7isxzcnJCZWUlfvvtN9pRmP9ACMHly5fh5OSEESNGoHv37sjLy4O/v3+dTt9Zvnw5pk6dCj09PSGkFS2pmuoEgJs3b2LSpEnIzMwU2YnmiYmJ8PT0RFlZGUJDQ9GvXz+2BUIIxo0bB2tra/j4+NCOwgDYsGEDbty4gUOHDtGOwvwFj8fD8ePHERoairKyMnh6emLcuHH1ujfp06dP4eDggMzMTDRt2lSAaSmhPOIUOD6fT+zs7Mj58+dF3u+xY8eIubk56d69O0lKShJp/9IuJSWF6OjokM+fP9OOwvzPx48fibq6ulRMfUmDiooKEhUVRUxNTcmPP/5ITpw4QXg8nkDanjx5MvHz8xNIW+JA6gofIYRERUWRwYMHU+m7urqaREVFEX19fTJ8+HCSkZFBJYe0GTJkCFm9ejXtGMw/uLm5kYCAANoxZFpxcTFZuXIl0dPTI/369SMJCQkCvfaanp5OtLS0yMePHwXWJm1SWfhKS0uJpqYmefLkCdUMoaGhRFNTk7i6urJPxfVw584doq+vT8rKymhHYf4hNTWV6OrqksrKStpRZM7bt2+Jj48P0dTUJGPGjCEPHjwQSj8uLi4kJCREKG3TIlWLW/7UoEEDTJo0ieqpHg0aNICnpyeysrLwww8/wMbGBkuWLMHHjx+pZZJUvr6+8PX1haqqKu0ozD9YW1vD3Nwcx48fpx1FZjx9+hSzZ8+GhYUFioqKcPv2bRw4cAB2dnYC7+vhw4dITEzEnDlzBN42TVJZ+ADAzc0NO3fuREVFBdUcTZo0QXh4OJKTk/HmzRuYmZlh9erV1HNJisTERGRnZ2Pq1Km0ozD/YdasWdi0aRPtGFLv0aNHGD9+PBwcHNC4cWM8fvwYmzdvFuoNtf39/eHl5YWGDRsKrQ8apLbwmZiYwMHBQWxWnLVo0QI7duzA1atXkZiYCDMzM+zatYttgfgGQgh8fHwQEBBQ78PHGeEZMmQI8vLykJycTDuKVPrtt98waNAg9OnTBzY2Nnjy5AlCQkLQrFkzofablJSEhw8fYubMmULthwrac63CdPr0adK+fXvaMb7qt99+I507dybW1tbk9OnTbCPwV5w7d45YWFgQLpdLOwrzHUFBQWTGjBm0Y0gNPp9P4uLiSOfOnYmRkRHZvHmzyK9xOzk5kW3btom0T1GR6sLH5XKJgYEBuX37Nu0oX8Xn88nJkyeJlZUV6dKlC7lx4wbtSGKDz+cTBwcHcvjwYdpRmBoQ1alJ0q66uprs3buX2NrakjZt2pADBw6Q6upqkeeIj48nxsbGpKqqSuR9i4LUTnUCgLy8PNzc3AR21wZB43A4+Omnn5CSkoKpU6di9OjRGDZsGNLT02lHo+7EiRPg8XgYMWIE7ShMDYjq1CRpVVZWhoiICJiamiIqKgrh4eF48OABxowZAwUFBZFmIf+7xBAYGFivTe9ijXblFbbCwkKirq5OCgoKaEf5rrKyMrJy5UrStGlTMm3aNPL8+XPakajgcrlfpoAZyXHjxg1ibGwssE3TsuD9+/ckODiYaGtrkyFDhpCbN2/SjkTi4uKItbW1VF9ikOoRHwBoampi6NChiI6Oph3lu1RVVbFo0SJkZ2dDS0sLrVu3hqenJz58+EA7mkgdPHgQjRs3xsCBA2lHYWrB0dERampquHjxIu0oYu/Vq1dYvHgxjI2NkZ2djatXr+LEiRNwdHSkmovP58PX1xdBQUGQl5enmkWYpL7wAX8st968ebPErKBUV1dHSEgIHj16hPfv38PMzAzh4eEoLy+nHU3oqqursXTpUixfvpyddyphOBwOZs+ezbY2fEN2djZcXV1hY2OD6upqPHz4ELt27YKVlRXtaACA2NhYyMvLY+jQobSjCJVMFL527dpBR0cHZ8+epR2lVvT19REVFYXExEQkJSXBzMwM0dHR4HK5tKMJTUxMDFq2bIlevXrRjsLUwZgxY3D79m08efKEdhSxcu/ePbi4uKBTp07Q1dVFVlYW1q1bh5YtW9KO9gWPx4O/vz+Cg4Ol/kOnTBQ+QLI32VpaWuLYsWM4fPgwYmJi0Lp1a5w4cQJEum6sgcrKSixbtgzBwcG0ozB11KBBA0yePBmbN2+mHYU6Qgji4+PRp08fDBkyBI6OjsjLy0NgYKBY3uFg3759aNq0Kfr27Us7ivDRvsgoKuXl5URbW5tkZmbSjlIvf+7vsbW1JY6OjiQxMZF2JIFZv349GThwIO0YTD3l5uYSTU1NUlpaSjsKFTwej8TGxpL27dsTc3NzsmPHDrE/y7SyspIYGhqSa9eu0Y4iEjJT+AghxMvLi8yfP592DIHgcrkkJiaGtGrVigwaNIg8evSIdqR6KSkpIc2aNRPaQbuMaA0cOJBER0fTjiFSlZWVJDo6mpibm5P27duTY8eOScwK182bN5M+ffrQjiEyMlX4nj59Spo0aUJKSkpoRxGY8vJysmbNGqKlpUUmT55M8vPzaUeqk9DQUDJq1CjaMRgBOXfuHLGzs5OJE4k+f/5MVq9eTfT19Unv3r1JfHy8RH3fZWVlRF9fn9y5c4d2FJGRmWt8ANCqVSt06dIF+/fvpx1FYFRUVPDrr78iOzsbenp6sLe3x6JFi1BUVEQ7Wo19+vQJq1evRmBgIO0ojID06dMHJSUluHXrFu0oQlNYWIiAgAAYGhoiKSkJJ0+exMWLF9GzZ0+JWhyyefNmtG/fHu3bt6cdRWRkqvABfyxyiYiIkLqFIT/88AOWL1+OR48eoaSkBObm5ggJCUFZWRntaN+1Zs0a9O/fH5aWlrSjMAIiJycHd3d3sT01qT6ePXuGefPmwczMDK9fv8bNmzdx+PBhODg40I5Wa58/f0ZYWBiWLVtGO4pIyVzhc3Z2RllZGW7cuEE7ilDo6elhy5YtuHnzJu7fvw9TU1Ns27ZNbLdAFBYWYtOmTQgICKAdhRGwyZMn4+zZs3j79i3tKAKRlpaGSZMmwd7eHsrKykhNTcW2bdtgampKO1qdbdiwAU5OTrC1taUdRaRkrvDJycl9GfVJMzMzMxw5cgTHjx/HgQMHYGNjg2PHjondSDc8PBwuLi4wMjKiHYURMA0NDYwaNQpRUVG0o9TLrVu3MGTIEDg5OcHc3Bw5OTkIDw+Hnp4e7Wj18uHDB6xbt04mLzFwiLi9E4rAx48fYWhoiPT0dKHf00ocEEJw4cIFeHl5QUVFBaGhoejRowftWHj9+jWsra3x6NEj6Ovr047DCEFycjIGDhyIvLw8iTrwmBCC8+fPIzQ0FM+ePcPixYsxZcoUqKqq0o4mMD4+Pnj79i22b99OO4rIyWThA4CZM2eiefPm8PPzox1FZPh8Pg4cOAA/Pz9YWFggJCQEbdq0oZZn9uzZUFJSwpo1a6hlYISva9eumDdvHkaOHEk7yndxuVwcPXoUoaGh4PP58PLygouLi8jvkCBs7969g6WlJR48eCBWp8eIDL0FpXQlJycTfX19qb3f1LdUVFSQ9evXE21tbTJ+/HiSl5cn8gx5eXmkSZMm5O3btyLvmxGtgwcPkh49etCO8U3l5eVk8+bNxMjIiHTp0oXExcVJ1JaE2po/fz6ZM2cO7RjUyNw1vj+1bt0ahoaGOHnyJO0oIqesrIy5c+ciOzsbRkZGcHBwwK+//orCwkKRZQgKCoKbmxu0tbVF1idDx7Bhw5CZmYnU1FTaUf7l06dPCA0NhaGhIc6cOYOYmBhcv34dAwcOlKgtCbXx4sUL7N69G0uWLKEdhRqZLXwAZGKRy7eoqakhMDAQaWlpqKqqgoWFBYKDg1FaWirUfrOysnDq1CksWrRIqP0w4kFJSQmurq6IjIykHeWLN2/ewMvLC0ZGRkhLS8PFixdx+vRpdOnShXY0oQsKCsKMGTNkYn3Df6I95KSpsrKS6OrqktTUVNpRxEJ2djYZPXo00dXVJZGRkUKbBh4zZgwJDg4WStuMeHr58iVRV1cnHz9+pJojJyeHzJw5k2hoaJDZs2dTmeanKScnh2hqapLCwkLaUaiS6RGfkpISZsyYIVafRGkyMTHBwYMHcfr0aRw7dgxWVlY4fPiwQLdApKSk4OrVq5g3b57A2mTEn56eHvr06YOYmBgq/T98+BBjx47Fjz/+CC0tLWRkZGDjxo0wMDCgkoeWwMBAzJkzB5qamrSj0EW78tL24sULoqGhQT59+kQ7iti5ePEiadu2LWnXrh25cuWKQNr86aefyJo1awTSFiNZEhMTiZmZmcgObubz+SQhIYH069eP6OnpkZUrV5Li4mKR9C2O0tLSiLa2NnuvIzJ2SPV/GTlyJNm0aRPtGGKJx+ORAwcOECMjI9KnTx9y//79Ord1+/Zt0rx5c1JeXi7AhIyk4PP5pHXr1uTixYtC7YfH45ETJ06Qjh07ElNTUxIVFUUqKiqE2qckGDFiBAkPD6cdQyywwkcIuXr1KrG0tJTq5cv1VVlZSTZt2kSaNWtGxo4dS3Jzc2vdRu/evcmWLVuEkI6RFFu3biVDhgwRSttVVVVk165dxNLSkjg4OJAjR44QLpcrlL4kzb1794ienp7M3iPxn1jhI398ErW2thbYdJ40+/z5MwkMDCRNmjQhc+bMqfE+vISEBGJoaCj2N+RkhKukpIQ0adJEoItKSkpKyLp160iLFi2Ik5MTuXTpEvsQ+w/9+/dns1p/IdOLW/7E4XBkfmtDTTVq1Aj+/v5IT08Hh8OBpaUlAgMD8fnz5/98DiEEPj4+WLp0KZSUlESYlhE3DRs2xMSJE7Fly5Z6t1VUVITAwEAYGhri+vXriI2NxeXLl+Hs7Cy1e/Dq4saNG3j8+DGmT59OO4r4oF15xUVxcTHR0NAgz58/px1FouTm5pJx48aRZs2akY0bN351RHfu3DliaWnJpp0YQgghWVlZREtLq87Xep89e0bmz59PNDQ0yNSpU0lGRoaAE0oPPp9PunfvTqKjo2lHEStsxPc/jRs3xs8//4ytW7fSjiJRjIyMsG/fPpw9exZxcXGwtLTEgQMHwOfzAfwx2vP19cWyZcsgLy9POS0jDkxNTeHg4IBDhw7V6nkZGRmYOnUq2rRpAzk5OaSkpCA6Ohrm5uZCSir5rly5gtevX2PixIm0o4gX2pVXnDx+/Jjo6OiwFWD1cOXKFdKuXTtib29PLl68SGJjY4mdnZ3IlrAzkuH06dOkffv2NXrs7du3ybBhw4i2tjZZtmwZKSoqEnI66cDn80mHDh3IgQMHaEcRO2zE9xeWlpawtrZGbGws7SgSq1evXrhz5w68vb3h7u6OiRMnYtKkSZCTY79qzP/r378/CgsLcefOna9+nRCCixcvolevXhg1ahR69uyJJ0+ewM/PD02aNBFxWsl0+vRpVFRUwMXFhXYU8UO78oqbY8eOkU6dOtGOIRV27txJjIyMSLNmzcjo0aNJdnY27UiMGAkPDycTJkz4299xuVxy6NAhYm9vT6ysrMju3btl8g4q9cXj8Ujr1q3JyZMnaUcRS6zw/UN1dTVp0aIFefDgAe0oEq2qqooYGxuT+Ph4UlJSQoKDg4mmpiZxd3cnr1+/ph2PEQOFhYVEXV2dvHv3jlRUVJCtW7cSExMT4ujoSE6dOsWmx+vhwIEDpEOHDmxbx39g80//oKCggJkzZ7KtDfW0a9cutGrVCj179kTDhg3h4+ODjIwMKCkpwdraGv7+/iguLqYdk6FIU1MTgwYNwsSJE7/cImzHjh24ceMGBg8ezKbH64jL5SIgIADLly9n2zr+g8zegf1b3r59CwsLCzx58gQaGhq040iciooKmJmZ4fDhw+jYseO/vv706VP4+/vjwoULWLJkCX755RcoKytTSMrQ8vbtW2zYsAERERGorq5GYmIiHBwcaMeSCjt27MCePXsQHx/PCt9/YB+pvkJHRwcDBgzAzp07aUeRSFu3bkWbNm2+WvQAwMDAALt378alS5dw8eJFWFhYYO/evV+2QDDSKy8vD7NmzYKFhQU+fPiA+/fvo02bNnj+/DntaFKhsrISy5YtQ3BwMCt630J7rlVc3bhxgxgbG7PrDLVUUlJCmjVrVqtrpAkJCeTHH38kbdq0IefOnWPXJaRQcnIyGTduHGnSpAnx9vYmb968+fK1ffv2EScnJ4rppMemTZtI//79accQe6zw/Qc+n0/s7e3JuXPnaEeRKCEhIcTFxaXWz+Pz+SQ2NpaYm5uTHj16kNu3bwshHSNqiYmJZMCAAURXV5eEhYV99Ua0FRUVREdHhzx+/JhCQulRWlpK9PT0yL1792hHEXvsGt83REdH48SJEzh9+jTtKBLh48ePMDU1xfXr12FhYVGnNrhcLnbu3InAwEB07NgRy5cvZydzSBg+n4+zZ88iNDQUb968gYeHByZOnAgVFZX/fI6fnx8+fvyIjRs3ijCpdFm5ciVu376No0eP0o4i9ljh+4aysjK0bNkSv//+OwwNDWnHEXv+/v549uwZdu3aVe+2ysrKsGHDBqxatQojR45EQEAAdHV16x+SEZrq6mocOnQIYWFhUFBQgJeXF0aOHFmjo+pevHiB1q1bIz8/H40bNxZBWulSXFwMExMTJCQkwMrKinYcsccWt3xDgwYNMGnSJIGcJC/tCgsLERERgYCAAIG016BBA3h5eSEzMxONGzeGjY0NfHx88OnTJ4G0zwhOWVkZNm3aBFNTU0RHR2PVqlW4f/8+Ro8eXePzWZs3b45evXphz549Qk4rndauXYt+/fqxoldTdGdaxV92djZp2rQpKSsrox1FrC1atIi4ubkJrf38/HwyefJkoqWlRVavXs3u4i4G3r9/T4KCgoi2tjYZOnQouXXrVr3aYzeErpvCwkKiqalJcnJyaEeRGGzE9x0mJiZo3759rU+SlyWvXr1CdHQ0fHx8hNZHy5YtsXPnTsTHxyMhIQHm5uaIiYkBj8cTWp/M1718+RKLFi2CsbExcnNzkZCQgOPHj//n9pWa6t69O+Tk5JCQkCCYoDIiPDwcI0aMgLGxMe0okoN25ZUEcXFxpF27drRjiC13d3eyYMECkfZ5/fp10qlTJ2JjY0Pi4uLYKEEEMjIyyLRp04iGhgaZP38+efbsmcD7iIyMJMOHDxd4u9Lq9evX7D6idcAWt9QAj8eDqakpDh48iA4dOtCOI1aePn0KBwcHZGRkQEtLS6R9E0Jw6tQpeHt7o2nTpggLC4Ojo6NIM8iCu3fvIjQ0FNeuXcOsWbMwZ84caGpqCqWvz58/o1WrVkhOTkaLFi2E0oc0mTt3LuTl5bF27VraUSQKK3w1tHLlSqSmpiImJoZ2FLEydepU6OvrIygoiFoGLpeL3bt3IyAgAO3bt8eKFSvqvJ2C+QMhBPHx8QgNDUVGRgYWLlyI6dOno1GjRkLve+7cuVBTU0NwcLDQ+5Jkz549g729PdLT06GtrU07jkRhha+GioqKYGxsjOzsbJGPbMRVZmYmunTpguzsbKirq9OOg/LycmzatAnh4eEYOnQoli5dCn19fdqxJAqPx8OJEycQGhqKkpISeHp6Yty4cVBSUhJZhoyMDPTo0QP5+fnsDNdvmD59OnR0dLB8+XLaUSQOW9xSQ5qamhg2bBiio6NpRxEbAQEB+PXXX8Wi6AGAqqoqFi9ejKysLGhqasLW1hZeXl748OED7Whir7KyEtHR0bCyskJ4eDh8fHyQlpaGyZMni7ToAYCFhQVsbW3ZRuxvyM7OxsmTJ7Fo0SLaUSQTvcuLkufu3bukVatWhMvl0o5C3cOHD4mOjg75/Pkz7Sj/6fnz52TatGmkadOmJDw8nG1J+Yri4mKyatUqoq+vT/r27UuuXr0qFguFTpw4QTp27Eg7htgaO3YsCQ4Oph1DYrERXy04ODigWbNmOHPmDO0o1Pn7+8PLy0sk13zqqnnz5ti+fTsSExNx8+ZNmJubY+fOnWwLBICCggL4+/vDyMgIv//+O06fPo3z58+jR48eYnGq/6BBg/Dq1Svcu3ePdhSx8+jRI8THx2PevHm0o0gsVvhqadasWTJ/k9rbt2/j/v37+OWXX2hHqRFLS0scP34chw4dws6dO9G6dWucPHkSRAYvb+fn52Pu3LkwNzfHu3fvcOvWLRw8eBD29va0o/2NvLw83NzcZP619jX+/v7w8PAQ6w+dYo/2kFPSlJeXE21tbZKZmUk7CjXOzs5ky5YttGPUCZ/PJ3FxccTGxoZ06tSJXL9+nXYkkXj06BGZMGECadKkCfHw8CCvXr2iHem73r17R9TV1UlhYSHtKGLjzp07RF9fn03b1xMb8dWSiooKpk6disjISNpRqEhISMCTJ08wdepU2lHqhMPhYODAgXj48CFcXV3x888/46effkJaWhrtaEJx8+ZN/PTTT3B2doalpSVyc3MRFhYmEQd+a2lp4aeffmILyv7C19cXvr6+UFVVpR1FstGuvJLo6dOnpEmTJqSkpIR2FJHi8/mkc+fOZPfu3bSjCEx5eTlZvXo10dLSIlOmTBHKaSSixufzyZkzZ0jXrl2JoaEhiYyMlNgRwp07d4iBgQFbUEYIuXbtGjE0NCSVlZW0o0g8NuKrg1atWqFr167Yt28f7Sgidf78ebx//x7jxo2jHUVgVFRUsGDBAmRlZUFXVxd2dnZYvHgx3r9/TztarXG5XOzfvx92dnbw9vaGm5sbsrKy4ObmJrEjhPbt20NLSwtnz56lHYUqQgh8fHywdOlSkW8vkUq0K6+kunjxImndurVYLP0WBT6fT9q2bUuOHDlCO4pQvXz5ksycOZNoamqSkJAQUlpaSjvSd5WVlZGIiAhiaGhIunbtSs6ePStVv5cxMTGkb9++tGNQde7cOWJpaclGvgLCCl8d8Xg8YmZmJjOLI44ePUrs7e0Jj8ejHUUkMjIyyIgRI4i+vj7Ztm0bqa6uph3pXz58+EBWrFhBdHR0yODBg8lvv/1GO5JQlJeXEy0tLZldUMbn84mDg4PUf+gUJTbVWUdycnJwd3eXieXWPB4Pfn5+CA4OhpycbPzKmJub4+jRo4iNjcW+fftgY2OD48ePi8UWiNevX8PT0xPGxsZIT0/H5cuXcerUKXTu3Jl2NKFQUVHBtGnTZHZB2fHjx8Hj8TB8+HDaUaQH7coryT58+EDU1dUlYml4fezZs4d06tRJqqbPaoPP55OzZ8+S1q1bk44dO5KEhAQqObKzs4mrqyvR0NAgc+bMIU+fPqWSg4Y/F5SJ80lBwsDlcom1tTWJi4ujHUWqyMbHdyFRV1fH6NGjERUVRTuK0FRXV2Pp0qUIDg4WixM9aOBwOOjfvz8ePHiAWbNmYfLkyRg4cCBSUlJE0v/9+/cxevRoODo6QkdHB5mZmdiwYQNatWolkv7FQatWrdCtWzeZW1B28OBBqKmpYcCAAbSjSBfalVfSpaSkEH19fVJVVUU7ilBs3bqVODk50Y4hVioqKsi6deuItrY2mThxolBGXnw+n8THx5M+ffoQfX19snr1alJcXCzwfiTJpUuXiK2trczMPFRVVRFjY2MSHx9PO4rUYSO+erK1tYWRkRFOnjxJO4rAVVRUICgoiN325B+UlZUxb948ZGdno1WrVmjbti0WLFiAwsLCerfN5/Nx4sQJODo64pdffsHo0aORm5uLBQsWoHHjxgJIL7mcnJxQVVWF69ev044iErt27YKBgQF69uxJO4r0oV15pcHBgwdJjx49aMcQuHXr1pHBgwfTjiH2Xr9+Tdzc3IimpiYJDg6u08EGlZWVZOfOncTCwoK0a9eOHD16lC1d/4oNGzaQUaNG0Y4hdOXl5aRFixYkKSmJdhSpxAqfAFRWVhJdXV3y6NEj2lEEpqSkhDRr1ow8ePCAdhSJkZWVRVxcXIienh7ZvHlzjaa/P3/+TNauXUuaN29OnJ2dyeXLl2VmKq8uPn36RDQ0NMiLFy9oRxEq9qFTuNhUpwAoKSlhxowZUrXcesOGDejWrRvs7OxoR5EYpqamOHToEE6ePIkjR47A2toaR44c+eoWiKKiIixduhSGhoa4ceMGjh8/jkuXLsHJyUlmFxHVhJqaGsaOHYtt27bRjiI0paWlCA0NxbJly2hHkVoc8rVXJVNrr169go2NDZ4+fQo1NTXacerl48ePMDU1xfXr12FhYUE7jkQihODSpUvw8vKCgoICwsLC0LNnTzx//hyrV6/G7t27MWLECCxevBhmZma040qUtLQ0ODs7Iz8/XyqP7woNDcWDBw9w6NAh2lGkFit8AuTi4oJu3bph9uzZtKPUi5+fH168eIGdO3fSjiLx+Hw+Dh06BA8PD/D5fJSWlmLGjBmYP38+9PX1aceTWL169YKrqyvGjBlDO4pAsQ+dosGmOgVo1qxZiIyMFIvTPeqqoKAAkZGRCAgIoB1FKty5cweHDx9GVVUV2rZtCyUlJbx+/RpVVVW0o0m0WbNmYdOmTbRjCNyaNWswaNAgVvSEjBU+AerWrRvk5ORw9epV2lHqLCwsDKNHj4aBgQHtKBKLEIILFy6gZ8+eGDNmDJycnJCXl4fTp08jNzcXpqamaNeuHebNm4eCggLacSXSkCFDkJ+fj4cPH9KOIjAFBQWIiIhgHzpFgE11CtjmzZtx6dIlHDt2jHaUWvvzOmVqair09PRox5E4PB4PR48eRWhoKKqrq+Hl5YXRo0dDUVHxX4999+4dgoODsW/fPsybNw8LFixAo0aNKKSWXMuXL8fTp0+l5uSkRYsWoby8XCbO/6WNFT4BKykpQatWrfDw4UO0aNGCdpxacXd3R4MGDbBq1SraUSRKRUUFYmJisHLlSujo6MDb2xsDBgyo0YHeubm58PPzw9WrV+Hr64sZM2ZI5YINYXj79i0sLCzw5MkTaGho0I5TL69evYKtrS0ePXrEPnSKACt8QjB37lyoqakhODiYdpQay8vLQ7t27ZCRkQEtLS3acSTCp0+fsGXLFqxbtw4ODg7w8vJCly5d6tTWgwcP4OXlhdzcXAQHB8PFxUVm7oRRH+PHj/9yco4kc3d3R8OGDbFy5UraUWQCK3xCkJGRgR49eiA/Px/Kysq049TIlClT0Lx5cwQFBdGOIvbevn2L9evXY9u2bejXrx88PDzQunVrgbR95coVeHp6ghCCsLAwODs7C6RdaXXr1i1MmDABWVlZEvtB4c8PnZmZmWjatCntODJBMn9TxJyFhQVsbGwQGxtLO0qNZGRkIC4uDgsXLqQdRaw9efIE7u7usLS0xKdPn3Dnzh3s3btXYEUP+OM8yjt37sDT0xNubm7o3bs37t27J7D2pU3Hjh3xww8/4MKFC7Sj1NmyZcswa9YsVvREiBU+IZGk5dYBAQFYsGAB1NXVaUcRS8nJyRg3bhw6dOgADQ0NpKenIyIiAkZGRkLpT05ODi4uLnj8+DGGDx+OQYMGYezYscjNzRVKf5KMw+Fg9uzZEvNa+6eMjAycOXOGfegUNZEfkiYjqqurSYsWLcj9+/dpR/mmhw8fEh0dnTodrCzN+Hw+uXbtGunfvz/R1dUl4eHh5NOnT1SyfP78mQQFBRFNTU0ya9Ys8ubNGyo5xFVZWRlp2rQpycnJoR2l1lxcXEhISAjtGDKHjfiEREFBAb/88ovYL0328/ODl5cXGjZsSDuKWODz+Th16hQ6d+6MadOmYdiwYXjy5AkWL15M7Si6Ro0awdfXF+np6VBUVISVlRUCAgJQXFxMJY+4UVVVxZQpU7B582baUWrl4cOHSExMxJw5c2hHkT20K680e/v2LVFXVyfv37+nHeWrbt26RZo3b07Ky8tpR6GuqqqK7N69m1hbWxN7e3ty+PBhsb0t0JMnT8j48eOJjo4OWb9+PamoqKAdibonT54QTU1NUlpaSjtKjQ0aNIisX7+edgyZxEZ8QqStrY2BAweK7ZmXvr6+8PPzg4qKCu0o1JSVlWHjxo0wMTHBrl27sHbtWty7dw+jRo2CvLw87XhfZWhoiD179uDChQs4f/48LC0tsX//fvD5fNrRqDE0NISjoyMOHDhAO0qNJCUlITk5GTNnzqQdRTbRrrzS7ubNm8TY2JjweDzaUf4mPj6eGBsb1+iecdKoqKiILFu2jGhra5Phw4eT27dv045UZ1evXiUdOnQgdnZ25Pz58zJ7P7/z588TOzs7ifj+e/XqRbZt20Y7hsxihU/I+Hw+sbe3J2fPnqUd5Qs+n086depE9uzZQzuKyD1//pwsWLCAaGhokClTppDHjx/TjiQQfD6fxMbGEjMzM9KzZ09y584d2pFEjsfjERMTE/Lbb7/RjvJNV65ckekPneKATXUKGYfDwaxZs8Rqkcu5c+fw8eNHjB07lnYUkcnMzMS0adPQunVrEEKQnJyMHTt2wNLSknY0geBwOBg+fDjS0tIwZswYDB06FKNGjUJWVhbtaCIjJycndq+1fyKEwNfXF4GBgV89w5UREdqVVxaUlpYSTU1N8uTJE9pRCI/HI/b29uTo0aO0o4jEnTt3yPDhw4mWlhYJDAwkhYWFtCOJRGlpKVmxYgXR1NQkv/zyC3n16hXtSCLx4cMHoq6uTl6/fk07ylfFxcURa2trsV04JSvYiE8EGjRogMmTJ4vFcutjx459GR1IK0IILl++DCcnJ4wYMQLdu3dHXl4e/P39oampSTueSDRo0ADe3t7IzMxEw4YNYWNjA19fX3z69Il2NKFSV1eHi4uLWN6xgc/nw9fXF0FBQWK7cEpm0K68siInJ4c0bdqUlJWVUcvA5XKJpaWlWF1vFCQul0uOHDlCHBwciKWlJdm1axe7jvI/+fn5ZPLkyURbW5usWbNGqrdAJCcnEz09PbH7tz98+DBp166dRCy+kXas8IlQ//79yc6dO6n1v3v3btKpUyepe+FVVFSQqKgoYmpqSn788Udy4sQJsVtFKy5SUlLIoEGDSKtWrUhMTIzUTrl17dqVHD58mHaML7hcLrGwsCDnz5+nHYUhrPCJVFxcHHFwcKBSeKqqqoiRkRG5evWqyPsWluLiYrJy5Uqip6dH+vXrRxISEqSuqAtLYmIicXR0JLa2tuTMmTNS93M7dOgQ6d69O+0YX+zatYt07dpV6n7OkooVPhHicrnEyMiIJCUlibzvLVu2EGdnZ5H3Kwxv374lPj4+RFNTk4wZM4Y8ePCAdiSJxOfzyfHjx4mlpSXp1q0buXXrFu1IAlNVVUX09PRISkoK7SiksrKSGBgYkGvXrtGOwvwPW9wiQvLy8nBzcxP5cuuKigoEBQVJ1I1xv+bp06eYPXs2LCwsUFRUhNu3b+PAgQOws7OjHU0icTgcDB06FCkpKZg4cSJGjRqFESNGICMjg3a0elNUVISrq6tYbG3YsWMHzMzM0K1bN9pRmD/RrryypqioiKirq5N3796JrM+1a9eSwYMHi6w/QUtJSSHjx48nTZo0IV5eXmK7VF3SlZWVkbCwMNK0aVMyY8YM8uLFC9qR6uXVq1dEXV2dfPjwgVqGsrIyoq+vL5MHCogzNuITsSZNmmDYsGGIjo4WSX8lJSUIDQ2VyDur37hxA4MHD0afPn1gbW2NJ0+eICQkBM2aNaMdTSqpqqrCw8MDWVlZ0NDQgK2tLby9vfHx40fa0epEV1cXffv2RUxMDLUMmzdvRvv27dG+fXtqGZivoF15ZdHdu3dJy5YtRbKibvny5WT06NFC70dQ+Hw+iYuLI126dCFGRkZk8+bNVLeAyLJnz56RqVOnEi0tLbJy5UqJvIvH9evXiZmZGZVVvsXFxURHR4c8evRI5H0z38YKHyV/LrsXpg8fPpCmTZuSjIwMofYjCNXV1WTv3r3E1taWtGnThhw4cIBUV1fTjsUQQtLS0siQIUNIixYtyM6dOyVqCwSfzydt2rQhFy5cEHnfQUFBZNy4cSLvl/k+Vvgo2bNnD+ndu7dQ+/D19SVTpkwRah/1VVZWRiIiIoiBgQHp3r07OXfuHFvyLaZu3LhBunTpQqytrcnJkycl5t9p27ZtIr/G/f79e6KpqUmysrJE2i9TMxxCCKE93SqLKisr0bJlS1y/fh1mZmYCb7+goAAWFha4d+8eDAwMBN5+fX38+BGRkZHYsGEDOnbsCE9PTzg6OtKOxXwHIQRxcXHw9vaGuro6wsLC0LlzZ9qxvqm0tBStWrXC3bt3RfZaWLJkCd69e4ft27eLpD+mdljho2jJkiUoKyvDunXrBN72woULUVFRIRbLuf/q1atXWLduHaKjozF48GB4eHjAysqKdiymlng8Hvbs2QN/f3/Y29sjJCRErP8dFyxYAEVFRYSFhQm9r3fv3sHS0hIPHjxAy5Ythd4fU3us8FH07Nkz2NvbIz8/H40aNRJYuy9fvoStrS1SU1Ohp6cnsHbrIzs7GytXrsTRo0cxceJELFiwgL0pSIE/P1yFhYVh8ODBWLp0KVq0aEE71r/k5OTA0dERz549g6qqqlD7+vXXX8Hj8bBhwwah9sPUHdvOQFHLli3RtWtX7Nu3T6DtLl++HNOmTROLonfv3j24uLigU6dO0NXVRVZWFtatW8eKnpRQUVHBwoULkZWVBR0dHdjZ2cHDwwPv37+nHe1vTExM0L59exw6dEio/bx48QK7d+/GkiVLhNoPU08Ury8yhJCLFy8SW1tbgS0UePLkCWnSpAkpKCgQSHt1wefzyZUrV0jv3r2Jvr4+WbNmDfn8+TO1PIzovHz5kri6upKmTZuS0NBQsdqKIoqzcl1dXYmnp6fQ2mcEgxU+yng8HjE3NyeJiYkCaW/SpEnEz89PIG3VFo/HI7GxsaR9+/bE3Nyc7Nixg1RWVlLJwtCVnp5Ohg8fTvT19UlUVJRYbE0R9lm5OTk5RFNTkxQVFQmlfUZw2DU+MbBhwwbcvHkTBw8erFc76enp6NatG3JycvDDDz8IKN33VVVVYd++fQgLC4Oamhq8vb0xZMgQyMmxmXRZl5SUBC8vL7x9+xYhISEYMmQIOBwOtTyrVq1CcnIy9uzZI/C2J0yYAFNTU/j7+wu8bUawWOETA58+fYKBgQEeP34MXV3dOrfj4uKCtm3bwsvLS4Dp/ltJSQmioqKwZs0aWFpawtvbGz169KD6xsaIH0IIzp8/D09PTzRq1AihoaHUDmx+//49jI2NkZmZCW1tbYG1m5aWhp49eyInJwdqamoCa5cRDvaRXAz88MMPGD16NKKiourcxsOHD3H9+nXMmTNHgMm+rrCwEAEBATA0NMStW7dw4sQJXLx4ET179mRFj/kXDoeD/v3748GDB3Bzc8PEiRMxaNAgPHr0SORZmjRpghEjRgh8f52/vz8WL17Mip6koDrRynyRkpJC9PT0SFVVVZ2eP2jQILJu3ToBp/q7/Px8MnfuXKKhoUFmzJjBTqVg6qSiooKsXbuWaGtrk0mTJpGnT5+KtP/79++T5s2bC+y64927d4menh4pLS0VSHuM8LERn5iwtbWFiYkJTpw4UevnJiUlITk5GTNnzhR8MPwxjTNp0iTY29tDWVkZqamp2LZtG0xNTYXSHyPdlJWVMX/+fGRlZaFFixZo27YtFi5ciKKiIpH0b29vj5YtW+L06dMCac/Pzw9LlixBgwYNBNIeI3ys8ImRWbNm1emkFR8fH/j5+UFFRUWgeZKSkjB06FA4OTnB3NwcOTk5CA8PF4v9gYzk++GHHxAUFITU1FSUl5fD3NwcK1asQGlpqdD7nj17NjZt2lTvdm7cuIHHjx9jxowZAkjFiAztISfz/6qqqoiurm6tbmNy5coVYmxsXOcp0n/i8/nk3LlzpHv37sTAwIBERESI1V4sRnplZmaSUaNGET09PbJlyxaB/U5/TWVlJWnWrBlJS0urcxt8Pp90796d7NixQ4DJGFFgIz4xoqioCFdXV0RGRtbo8YQQ+Pr6YunSpVBUVKxX31wuFwcPHoS9vT08PDzg6uqK7OxsuLu7C/2IJ4YBADMzMxw+fBgnTpzAoUOHYGNjg9jYWBAhLDxXUlLCjBkzavxa+5rLly/jzZs3mDBhggCTMSJBu/Iyf/fy5Uuirq5OPn78+N3HxsXFESsrq3rdH628vJxs3ryZGBkZkS5dupC4uDiJud0MI734fD45f/48sbOzIx06dCBXr14VeB8vXrwgGhoa5NOnT3XK1759e3Lw4EGB52KEj434xIyenh569+6N3bt3f/NxfD4fvr6+CAoKgry8fK37+fTpE0JDQ2FoaIgzZ84gJiYG169fx8CBA9mWBIY6DoeDvn374t69e5g/fz6mTp2KAQMGIDk5WWB96Ovrw8nJqU6b2U+dOoXKykqMGjVKYHkYEaJdeZl/u3btGrGwsPjmyOvIkSOkbdu2tR6dvX79mnh6epImTZqQ8ePHk5SUlPrGZRihq6ysJBs2bCA6Ojpk/Pjx5MmTJwJpNyEh4buvtX/i8XjE1taWnDx5UiAZGNFjIz4x1LVrVygoKODE+SvYci0X8w89wNSY3zH/0ANsuZaLd8Xl8Pf3R3BwcI1HZ7m5uXBzc4OVlRVKS0tx79497NmzB7a2tkL+bhim/pSUlDBnzhxkZ2fD2NgY7dq1w/z581FQUFCvdrt16wZ5eXnEx8fX+DmHDx+GqqoqBg8eXK++GXrYkWViKPn5RyzaeQk5pUpQUlJCJZf/5WsqCnLg8nhQKMjCQf8psGuh8c22Hj58iLCwMFy6dAlubm6YM2eOQI9qYhga3r59i+DgYOzfvx/z58/Hr7/+Wud7Wm7ZsgUXL17EsWPHvvtYLpcLa2trREREwNnZuU79MfSxEZ+Y2Zv0FGOikpBT3gBETuFvRQ8AKrh8cAkHlU3NMTbqNvYmPf1XG4QQXLt2Df3798fAgQPh4OCAvLw8BAUFsaLHSAUdHR1s3LgRd+7cQXp6OszMzBAZGYnq6upatzV+/HgkJCTg2bNn333s7t27oaenBycnp7rEZsQEG/GJkb1JT7H8bDrKq/nff/D/qCrKwWeAJcZ3NACfz8fp06cRGhqKoqIieHh4YMKECVBWVhZiaoah7/79+/Dy8kJeXh6Cg4MxatSoWt0dZN68eWjUqBGWL1/+n4+prKyEubk59u/fj06dOgkiNkMJK3xiIvn5R4yJSkJ5Na/Wz1VRlMNEvffYu2E5GjRoAC8vLwwbNqxOqz0ZRpJdvnz5y91JwsLCajwyy8zMRLdu3ZCfn/+fJyBt2rQJ586dw5kzZwSWl6GDFT4x4brnLi6lv0Vd/jUIn49GH3OxfpQNnJyc2HYERqbx+XwcOXIEPj4+MDIyQmhoKNq2bfvd5/Xp0wfDxk4Ex8gRGW+KUVzBhZqKAiyaqWGQlSY6tLFCXFxcjdpixBsrfGKgsKQSncPi/3U9rzaUFeRw07MXNBuxaU2GAYDq6mpERUUhKCgIPXv2RFBQEIyNjb/62OTnH+F34DpSCnlQVlb+14Kyai4XjUueIcbjZ7RpoS6i74ARFra4RQwcvfei3m1wABy9X/92GEZaKCoqwt3dHdnZ2bC0tESHDh0wZ84cvHv37m+P+3NB2aOPcoC84lcXlPEgh0+NDDAmKumrC8oYycJGfGJg/qEHOPHwVb3b6dhMDm52DaCoqAglJaUa/cmuAzKyoqCgAMuXL8eePXswZ84cLFy4ECfTiuq1oIyRTKzwiYGpMb8jPuPd9x/4HQ0+5EIrPRZVVVWorq7+5p9//j+Hw6lxkfzWn6JuQ15enl3LZOokLy8Pfn5+uPIwBw0H+4Bbh4kvVUV5HHLtiNbN1QUfkBE6VvjEgKBGfMPs9LF2tF2NH08IAY/H+26R/F7xrM+fdX0uj8cTq0Jc0zYUFRVZwRYTozddwe0XZQCn9oWPwwH6Wulgy/h2QkjGCJsC7QAMYNFMDcoKb+q1uEVFQQ4Wuo1r9RwOhwMFBQUoKChI3K2H+Hy+QAvwP9v6/PmzUIo5l8uFgoIC9QJclz9rsy9O3BWWVOLh26o6FT0AIAS4mlmAopJKtqBMArHCJwZGOjTH2stZ9WqDABjZtrlgAkkAOTk5KCsrS9zmfEIIqqurhTYSLi8vR3FxsVBG5PLy8mJRgGvb1temxQW5oGxmt6+vFGXEFyt8YqBpI2V0N9Oq8z4+Dgfoaa7FPnlKgD+vqSopKaFhw4a049TYn9PiwprWrqqqQklJiVA+EBBC/l00u7tCzujHev1MKrh8ZLz+LKCfMCNKrPCJiVk9THA9u7BuJ7coyMO9h4kQUjHMH/46LS5p/ryO/dfiueBkNm7l179oFVfU/mxQhj7pmbSXcG1aqMNngAVUFWv3T/LH0moLtrqMYf6DvLw8VFRU0LhxY2hqakJXVxc6GrW7Hv5f1FQUBdIOI1qs8ImR8R0N4DPAEqqK8vjewj8O548l1Ww/EcPU3h8Lyur39leXBWWMeGDbGcRQyouPiEzIwdXMAnDwx7WEP6koyIHgj2t67j1M2EiPYeqAHRMo21jhE2NFJZU4ev8FMl5/RnFFNdRUFGGh2xgj2zZnLzaGqaf6HAzP9vFJNlb4GIaRSfW5FRg7uUWysWt8DMPIJLagTHZJ3tpkhmEYAflzYdjysxmo4PK+Oe3J4fyxdchngAVbUCbh2FQnwzAyjy0oky2s8DEMw/wPW1AmG1jhYxiGYWQKW9zCMAzDyBRW+BiGYRiZwgofwzAMI1NY4WMYhmFkCit8DMMwjExhhY9hGIaRKazwMQzDMDKFFT6GYRhGprDCxzAMw8gUVvgYhmEYmcIKH8MwDCNTWOFjGIZhZAorfAzDMIxMYYWPYRiGkSms8DEMwzAyhRU+hmEYRqawwscwDMPIFFb4GIZhGJnCCh/DMAwjU1jhYxiGYWQKK3wMwzCMTPk/aIFKJF8xSoMAAAAASUVORK5CYII=\n"
     },
     "metadata": {}
    }
   ],
   "source": [
    "g = nx.random_regular_graph(4,5)\n",
    "nx.draw(g)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 4,
   "metadata": {
    "tags": []
   },
   "outputs": [
    {
     "output_type": "stream",
     "name": "stderr",
     "text": "[WARNING] DEBUG(3475,7ff67bea1740,python):2022-01-20-04:21:14.823.884 [mindspore/ccsrc/debug/debugger/debugger.cc:88] Debugger] Not enabling debugger. Debugger does not support CPU.\ntrain step: 0 , cut: [4.9972315]\ntrain step: 10 , cut: [5.8756557]\ntrain step: 20 , cut: [5.938826]\ntrain step: 30 , cut: [5.9884467]\ntrain step: 40 , cut: [5.991696]\ntrain step: 50 , cut: [5.996513]\ntrain step: 60 , cut: [5.9990983]\ntrain step: 70 , cut: [5.9995904]\ntrain step: 80 , cut: [5.999978]\ntrain step: 90 , cut: [5.9999433]\ntrain step: 100 , cut: [5.999985]\ntrain step: 110 , cut: [5.999996]\ntrain step: 120 , cut: [5.999998]\ntrain step: 130 , cut: [5.999999]\ntrain step: 140 , cut: [6.]\ntrain step: 150 , cut: [6.]\ntrain step: 160 , cut: [6.]\ntrain step: 170 , cut: [6.]\ntrain step: 180 , cut: [6.]\ntrain step: 190 , cut: [6.]\n{'g0': -0.0906218, 'b0': 0.49036992, 'g1': -0.077761784, 'b1': 0.34725758, 'g2': 0.038497396, 'b2': -0.063613445, 'g3': -0.37427723, 'b3': 0.21271546}\n"
    }
   ],
   "source": [
    "# pylint: disable=W0104\n",
    "p = 4\n",
    "optimal_params = qaoa.train_params(g, p)\n",
    "print(optimal_params)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 10,
   "metadata": {
    "tags": []
   },
   "outputs": [
    {
     "output_type": "stream",
     "name": "stdout",
     "text": "train step: 0 , cut: [6.503772]\ntrain step: 10 , cut: [9.655039]\ntrain step: 20 , cut: [10.6632595]\ntrain step: 30 , cut: [10.72497]\ntrain step: 40 , cut: [10.8149605]\ntrain step: 50 , cut: [10.971073]\ntrain step: 60 , cut: [11.525713]\ntrain step: 70 , cut: [11.846874]\ntrain step: 80 , cut: [11.910953]\ntrain step: 90 , cut: [11.974449]\ntrain step: 100 , cut: [11.973851]\ntrain step: 110 , cut: [11.979338]\ntrain step: 120 , cut: [11.983462]\ntrain step: 130 , cut: [11.984207]\ntrain step: 140 , cut: [11.98447]\ntrain step: 150 , cut: [11.984814]\ntrain step: 160 , cut: [11.98514]\ntrain step: 170 , cut: [11.985456]\ntrain step: 180 , cut: [11.985773]\ntrain step: 190 , cut: [11.986107]\n100%|██████████| 1000/1000 [00:34<00:00, 28.87it/s]\n"
    },
    {
     "output_type": "error",
     "ename": "NameError",
     "evalue": "name 'plt' is not defined",
     "traceback": [
      "\u001b[0;31m---------------------------------------------------------------------------\u001b[0m",
      "\u001b[0;31mNameError\u001b[0m                                 Traceback (most recent call last)",
      "\u001b[0;32m/tmp/ipykernel_22109/1861968643.py\u001b[0m in \u001b[0;36m<module>\u001b[0;34m\u001b[0m\n\u001b[1;32m     28\u001b[0m         \u001b[0mpar\u001b[0m \u001b[0;34m=\u001b[0m \u001b[0mnp\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mhstack\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0mpar0\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0moptimal_varibles2\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m     29\u001b[0m         \u001b[0mev_mat\u001b[0m\u001b[0;34m[\u001b[0m\u001b[0mi\u001b[0m\u001b[0;34m]\u001b[0m \u001b[0;34m=\u001b[0m \u001b[0mgrad_ops\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0mpar\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m[\u001b[0m\u001b[0;36m0\u001b[0m\u001b[0;34m]\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mreal\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0;32m---> 30\u001b[0;31m     \u001b[0mplt\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0msubplot\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0;36m2\u001b[0m\u001b[0;34m,\u001b[0m\u001b[0;36m3\u001b[0m\u001b[0;34m,\u001b[0m\u001b[0mint\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0;36m1\u001b[0m\u001b[0;34m+\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0mdegree\u001b[0m\u001b[0;34m-\u001b[0m\u001b[0;36m2\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m/\u001b[0m\u001b[0;36m2\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0m\u001b[1;32m     31\u001b[0m     \u001b[0mxxx\u001b[0m \u001b[0;34m=\u001b[0m \u001b[0mnp\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0marange\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0mng\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m*\u001b[0m\u001b[0;36m2\u001b[0m\u001b[0;34m*\u001b[0m\u001b[0mnp\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mpi\u001b[0m\u001b[0;34m/\u001b[0m\u001b[0mng\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m     32\u001b[0m     \u001b[0mplt\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mplot\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0mxxx\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0mev_mat\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n",
      "\u001b[0;31mNameError\u001b[0m: name 'plt' is not defined"
     ]
    }
   ],
   "source": [
    "ng =1000\n",
    "n = 13\n",
    "p = 10\n",
    "\n",
    "for degree in range(2,13,2):\n",
    "    g = nx.random_graphs.random_regular_graph(degree, n)\n",
    "    ham = Hamiltonian(qaoa.build_ham(g))              # 生成哈密顿量\n",
    "    init_state_circ = UN(H, g.nodes)             # 生成均匀叠加态，即对所有量子比特作用H门\n",
    "    ansatz = qaoa.build_ansatz(g, p)                  # 生成ansatz线路\n",
    "    circ = init_state_circ + ansatz              # 将初始化线路与ansatz线路组合成一个线路\n",
    "    sim = Simulator('projectq', n)                     # 创建模拟器，backend使用‘projectq’，能模拟5个比特（'circ'线路中包含的比特数）\n",
    "    grad_ops = sim.get_expectation_with_grad(ham, circ)            # 获取计算变分量子线路的期望值和梯度的算子\n",
    "    net = MQAnsatzOnlyLayer(grad_ops)                              # 生成待训练的神经网络\n",
    "    opti = nn.Adam(net.trainable_params(), learning_rate=0.05)     # 设置针对网络中所有可训练参数、学习率为0.05的Adam优化器\n",
    "    train_net = nn.TrainOneStepCell(net, opti)                     # 对神经网络进行一步训练\n",
    "\n",
    "    for i in range(200):\n",
    "        cut = (len(g.edges) - train_net()) / 2      # 将神经网络训练一步并计算得到的结果（切割边数）。注意：每当'train_net()'运行一次，神经网络就训练了一步\n",
    "        if i%10 == 0:\n",
    "            print(\"train step:\", i, \", cut:\", cut)  # 每训练10步，打印当前训练步数和当前得到的切割边数\n",
    "    pr = dict(zip(ansatz.params_name, net.weight.asnumpy()))\n",
    "    optimal_variables = np.array(list(pr.values()))\n",
    "    #搭建差分网格，绘制图像\n",
    "    ev_mat = np.zeros(ng)\n",
    "    optimal_varibles2 = optimal_variables[1:]\n",
    "    for i in trange(ng):\n",
    "        par0 = np.array([(i*np.pi*2)/ng])\n",
    "        par = np.hstack((par0, optimal_varibles2))\n",
    "        ev_mat[i] = grad_ops(par)[0].real\n",
    "    plt.subplot(2,3,int(1+(degree-2)/2))\n",
    "    xxx = np.arange(ng)*2*np.pi/ng\n",
    "    plt.plot(xxx, ev_mat)\n",
    "    plt.xticks(np.array([0, 2*np.pi]), ('0', r'$2\\pi$' ))\n",
    "    plt.title('degree='+str(degree))\n",
    "plt.subplots_adjust(left=None, bottom=None, right=None, top=0.85, wspace=0.5, hspace=0.5)\n",
    "plt.suptitle(\"Shape of Cost Function for n=13, p=10 and different degrees\", fontsize = 13)\n",
    "plt.figsave('Shape_of_Cost_Function.svg')"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 5,
   "metadata": {},
   "outputs": [
    {
     "output_type": "error",
     "ename": "NameError",
     "evalue": "name 'np' is not defined",
     "traceback": [
      "\u001b[0;31m---------------------------------------------------------------------------\u001b[0m",
      "\u001b[0;31mNameError\u001b[0m                                 Traceback (most recent call last)",
      "\u001b[0;32m/tmp/ipykernel_2488/2648353320.py\u001b[0m in \u001b[0;36m<module>\u001b[0;34m\u001b[0m\n\u001b[0;32m----> 1\u001b[0;31m \u001b[0ma\u001b[0m \u001b[0;34m=\u001b[0m \u001b[0mnp\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0marray\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0;34m[\u001b[0m\u001b[0;36m1\u001b[0m\u001b[0;34m,\u001b[0m\u001b[0;36m2\u001b[0m\u001b[0;34m,\u001b[0m\u001b[0;36m3\u001b[0m\u001b[0;34m]\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0m",
      "\u001b[0;31mNameError\u001b[0m: name 'np' is not defined"
     ]
    }
   ],
   "source": [
    "a = np.array([1,2,3])"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": []
  }
 ]
}